package cn.yangliu.task.socket;


import cn.yangliu.task.entity.Task;
import cn.yangliu.task.service.TaskService;
import cn.yangliu.task.service.impl.TaskServiceImpl;
import cn.yangliu.task.utils.AppUtils;
import com.alibaba.fastjson.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;

import java.lang.reflect.Method;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

/**
 * 作者 杨柳
 * 时间 2017-09-24 23:46
 * 描述
 */
public class TaskSockectServer implements InitializingBean{

    private final static Logger logger = LoggerFactory.getLogger(TaskSockectServer.class);
   private int port;

   private boolean enableSocket;

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public boolean getEnableSocket() {
        return enableSocket;
    }

    public void setEnableSocket(boolean enableSocket) {
        this.enableSocket = enableSocket;
    }

    public void start(){
        DatagramSocket socket=null;
        try {

             /*
         * 接收客户端发送的数据
         */
            // 1.创建服务器端DatagramSocket，指定端口
            socket = new DatagramSocket(port);
            // 2.创建数据报，用于接收客户端发送的数据
            byte[] data = new byte[10240];// 创建字节数组，指定接收的数据包的大小
            DatagramPacket packet = new DatagramPacket(data, data.length);
            // 3.接收客户端发送的数据
            logger.debug("****服务器端已经启动，等待客户端发送数据");

            while (true) {
                try{
                    socket.receive(packet);// 此方法在接收到数据报之前会一直阻塞
                    // 4.读取数据
                    String info = new String(data, 0, packet.getLength());
                    logger.debug("********客户端消息********"+info);

                    String responseInfo = todo(info);
                /*
                 * 向客户端响应数据
                 */
                    // 1.定义客户端的地址、端口号、数据
                    InetAddress address = packet.getAddress();
                    int port = packet.getPort();
                    byte[] resposeData = responseInfo.getBytes();
                    // 2.创建数据报，包含响应的数据信息
                    DatagramPacket resposePacket = new DatagramPacket(resposeData, resposeData.length, address, port);
                    // 3.响应客户端
                    socket.send(resposePacket);

                }catch (Exception e){
                    logger.error(e.getMessage(),e);
                }
            }
        } catch (Exception e) {
            // 4.关闭资源
            if (socket!=null){
                socket.close();
            }
            throw new RuntimeException(e);
        }
    }

    private synchronized String todo(String info){
        String msg = "操作成功";
        try{
            SocketInfo socketInfo = JSON.parseObject(info,SocketInfo.class);
            TaskService taskService = AppUtils.getBean(TaskService.class);
            Method method = TaskServiceImpl.class.getMethod(socketInfo.getAction(), Task.class);
            method.invoke(taskService,socketInfo.getTask());
        }catch (Exception e){
            logger.error(e.getMessage(),e);
            msg = "操作失败";
        }

        return msg;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        if (enableSocket){
            start();
        }
    }
}
